#pragma once
#include <stdint.h>

// avoid unused parameter warning
#define UNUSED(param) (void)(param)

// coroutine status enum
// 首次启动前
#define WO_STATE_READY 0
// 正在运行
#define WO_STATE_RUNNING 1
// 主动 yield
#define WO_STATE_SUSPENDED 2
// 已退出
#define WO_STATE_EXITED 3
// 等待 IO
#define WO_STATE_IO_WAIT 4
// IO 就绪
#define WO_STATE_IO_READY 5

#if defined(__x86_64__)
typedef uint64_t reg_t;
#define WOAPI
#elif defined(__i386__)
typedef uint32_t reg_t;
#if defined(__GNUC__)
#define WOAPI __attribute__((__cdecl__))
#elif defined(__MSVC__)
#define WOAPI __cdecl
#endif
#endif

typedef void (*WOAPI wo_routine_func_t)(void *);

// coroutine stack size
#define STACK_SIZE (1024 * 1024)

// coroutine context
// similar with ucontext but only general registers included.
typedef struct wo_context {
#if defined(__x86_64__)
  reg_t rax, rbx, rcx, rdx, rsi, rdi, rbp, sp, r8, r9, r10, r11, r12, r13, r14,
      r15;
#elif defined(__i386__)
  reg_t eax, ebx, ecx, edx, esi, edi, ebp, sp;
#endif
} wo_context_t;

// coroutine data struct. circular linked-list.
typedef struct wo_routine {
  wo_context_t ctx;        // 寄存器状态
  uint8_t *stack;          // 协程专属栈
  void (*func)(void *);    // 协程入口点
  void *args;              // 参数指针，存放到 RDI 寄存器
  int16_t state;   // 协程状态
  struct wo_routine *next; // 协程队列，环形链表
  struct wo_routine *prev; // 协程队列，环形链表
} wo_routine_t;

// coroutine scheduler struct.
typedef struct wo_scheduler {
  wo_context_t ctx;     // 调取协程的寄存器状态
  struct wo_routine *C; // 当前正在运行的协程
} wo_scheduler_t;
